home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_075
/
comm
/
wxmdmrecv.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
6KB
|
300 lines
/* Comm WXMODEM receive file routines */
#define WXMDMRECV 1
#include "globals.h"
#include <fcntl.h>
extern int WXch(), timedch();
extern void send_proto(), emits_rx();
extern int readchar();
static short eotflg, NAKsent, dirty;
static int index, errsect, naks;
WXmodem_rec(file)
UBYTE *file;
{
unsigned crchi, crclo, sect, comp;
int ch, secerrs;
unsigned count;
void chop_file();
ULONG bytes;
secerrs = errsect = naks = index = bytes = 0;
sector = 1;
cancel = eotflg = abort = dirty = FALSE;
while(secerrs < RETRYMAX)
{
if(abort) /* keyboard abort (ESC) */
{
abortxfer();
return FALSE;
}
if(cancel) /* remote sent CAN */
{
send_proto(ACK);
chop_file(index); close( fd );
if(( ch = timedch(5)) == CAN)
send_proto(ACK);
return TRUE;
}
/* start of block */
do { /* look for SYN/CAN/EOT */
ch = timedch(10);
if( ch == ERROR )
{
secerrs++;
send_proto(NAK); send_proto(errsect & 3);
}
if( (secerrs > RETRYMAX) || abort || cancel)
{
abortxfer();
return FALSE;
}
if(ch == EOT)
{
send_proto(NAK);
ch = timedch(5);
if(ch == EOT || ch == ERROR)
{
send_proto(ACK);
chop_file(index); close( fd );
return TRUE;
}
}
} while (ch != SYN);
/* got one SYN character -- gobble up the others */
while((ch = timedch(10)) == SYN) ;
/* we got a non SYN character
if SOH, then we have a block, if not...who knows, so start over again
*/
if(ch != SOH) continue;
/* block number and compliment */
sect = WXch(10); emit_rx_protocol((UBYTE)sect);
comp = WXch(10); emit_rx_protocol((UBYTE)comp);
if( sect == ERROR || comp == ERROR)
{
Nak();
continue;
}
/* start of data
clear out the last block and start a new one
*/
if(dirty)
{
movmem(xbuffer,&diskbuff[index++ * SECSIZ],SECSIZ);
dirty = FALSE;
}
crc = count = 0;
while( count < SECSIZ )
{
ch = WXch(10);
if( ch == ERROR ) break;
do_crc(ch);
xbuffer[ count++ ] = ch;
if(viewflg)
emit_vw(ch);
}
if( ch == ERROR )
{
Nak();
continue;
}
/* first CRC byte */
if((crchi = WXch(10)) == ERROR)
{
Nak();
continue;
}
do_crc(crchi);
/* second CRC byte */
if((crclo = WXch(10)) == ERROR)
{
Nak();
continue;
}
/* see if checksum is valid */
if(!verify_checksum( crclo ))
{
emits_rx(" Checksum error\n");
Nak();
secerrs++;
status(file,bytes,naks,errsect);
continue;
}
/* does the block number match the compliment? */
if((UBYTE)sect != (UBYTE)~comp)
{
Nak(); secerrs++;
continue; /* no: this isn't a real block! */
}
/* if this isn't the sector we're waiting for, try again */
if( (UBYTE)sect != (UBYTE)sector )
{
Nak();
continue;
}
/* otherwise, this must be a good sector and it must have good data,
so ACK it
*/
Ack(sect);
NAKsent = FALSE;
secerrs = 0;
sprintf(sbuff,"\rReceived block %d",sector);
emits_rx(sbuff);
/* accept the sector */
sector++; dirty = TRUE; bytes += SECSIZ;
status(file,bytes,naks,errsect);
if(index == numbufs)
{
sendchar(XOFF);
if(write(fd,diskbuff,numbufs * SECSIZ) != numbufs * SECSIZ)
{
emits_rx("\nERROR writing to file\n");
abortxfer();
return FALSE;
}
index = 0;
sendchar(XON);
}
}
abortxfer();
return FALSE;
}
/* send ACK */
Ack(sect)
int sect;
{
send_proto(ACK);
send_proto(sect & 3);
}
/* Send NAK unless we've already done so */
Nak()
{
if(!NAKsent)
{
send_proto(NAK);
send_proto(sector & 3);
errsect = sector;
NAKsent = TRUE;
}
naks++;
}
timedch(time)
int time;
{
int ch;
Process_window_event();
if(abort) return ERROR;
ch = readchar(time,0);
if(ch == TIMEOUT) return ERROR;
emit_rx_protocol(ch);
return ch;
}
WXch(time)
int time;
{
int gotdle,ch;
gotdle = 0;
Process_window_event();
if(abort) return ERROR;
while(TRUE)
{
ch = readchar(time,0);
if(ch == TIMEOUT) return ERROR;
switch (ch)
{
case DLE:
gotdle = 64;
continue;
case SYN:
return ERROR;
default:
return (ch ^ gotdle);
}
}
}
abortxfer()
{
int ch;
sendchar(XOFF);
chop_file(index);
sendchar(XON);
send_proto(CAN); send_proto(CAN); send_proto(CAN);
if(waitcan() == TRUE)
return TRUE;
return FALSE;
}
waitcan()
{
int ch,err;
err = 0;
emits_rx("\nAborting...Wait...\n");
while (readchar(2,0) != TIMEOUT)
;
send_proto(CAN); send_proto(CAN);
ch = readchar(5,0); ch = readchar(5,0);
do {
if(err++ == 3) break;
send_proto(ACK);
emits_rx("Sending abort...\n");
Delay(50L);
send_proto(CAN); send_proto(CAN);
ch = readchar(3,0);
} while( ch != CAN );
send_proto(ACK);
return TRUE;
}
sendWs()
{
int ch,err;
err = 0;
send_proto('W');
do {
ch = timedch(3);
if(ch == SYN)
return TRUE;
if(ch == ERROR)
send_proto('W');
} while ( err++ < 3 );
return FALSE;
}